﻿using System;
using System.Windows.Forms;
using Neovolve.Extensibility.VisualStudio.ReflectorLink.Properties;

namespace Neovolve.Extensibility.VisualStudio.ReflectorLink
{
    internal class Notifier : IDisposable
    {
        /// <summary>
        /// Defines the default timeout value in milliseconds.
        /// </summary>
        private const Int32 DefaultTimeout = 5000;

        /// <summary>
        /// Initializes a new instance of the <see cref="Notifier"/> class.
        /// </summary>
        public Notifier()
        {
            Disposed = false;

            Notify = new NotifyIcon();

            Notify.BalloonTipTitle = Application.ProductName;
            Notify.Icon = Resources.ReflectorIcon;
            Notify.Visible = false;

            Notify.BalloonTipClicked += (Notify_BalloonTipClicked);
            Notify.BalloonTipClosed += Notify_BalloonTipClosed;
            Notify.Click += Notify_Click;
            Notify.DoubleClick += Notify_DoubleClick;
        }

        private void Notify_DoubleClick(object sender, EventArgs e)
        {
            Notify.Visible = false;
        }

        private void Notify_Click(object sender, EventArgs e)
        {
            Notify.Visible = false;
        }

        /// <summary>
        /// Handles the BalloonTipClicked event of the Notify control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Notify_BalloonTipClicked(object sender, EventArgs e)
        {
            Notify.Visible = false;
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            if (Disposed == false)
            {
                Disposed = true;

                Notify.BalloonTipClicked -= (Notify_BalloonTipClicked);
                Notify.BalloonTipClosed -= Notify_BalloonTipClosed;
                Notify.Click -= Notify_Click;
                Notify.DoubleClick -= Notify_DoubleClick;
                Notify.Dispose();
            }
        }

        /// <summary>
        /// Shows the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        public void Show(String message)
        {
            Show(message, ToolTipIcon.Info, DefaultTimeout);
        }

        /// <summary>
        /// Shows the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="icon">The icon.</param>
        public void Show(String message, ToolTipIcon icon)
        {
            Show(message, icon, DefaultTimeout);
        }

        /// <summary>
        /// Shows the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="icon">The icon.</param>
        /// <param name="timeout">The timeout.</param>
        public void Show(String message, ToolTipIcon icon, Int32 timeout)
        {
            Notify.BalloonTipText = message;
            Notify.BalloonTipIcon = icon;

            Notify.Visible = true;
            Notify.ShowBalloonTip(timeout);
        }

        /// <summary>
        /// Handles the BalloonTipClosed event of the Notify control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Notify_BalloonTipClosed(object sender, EventArgs e)
        {
            Notify.Visible = false;
        }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="Notifier"/> is disposed.
        /// </summary>
        /// <value><c>true</c> if disposed; otherwise, <c>false</c>.</value>
        private Boolean Disposed
        {
            get;
            set;
        }

        /// <summary>
        /// Gets the notify.
        /// </summary>
        /// <value>The notify.</value>
        private NotifyIcon Notify
        {
            get;
            set;
        }
    }
}